/**
 * @author lei2jun
 */

import markdown from 'markdown'
import get from '@network/get'
import post from '@/network/post'
import Toast from "@/components/toast"
import { toAuthorLink } from '@/assets/libs/utils'

import { SET_TAB } from './appShell/common'

const RESET_TOPIC = 'RESET_TOPIC'
const TO_COLLECT = 'TO_COLLECT'
const ADD_UP = 'ADD_UP'
const ADD_REPLY = 'ADD_REPLY'
const SET_TOPIC = 'SET_TOPIC'
const SET_ERROR = 'SET_ERROR'

export {
  RESET_TOPIC,
  TO_COLLECT,
  ADD_UP,
  ADD_REPLY,
  SET_TOPIC,
  SET_ERROR
}

const topicInit = () => {
  return {
    author: {
      avatar_url: '',
      loginname: ''
    },
    title: 'data loading...'
  }
}

export const state = () => {
  return {
    /**
     * 帖子id
     * @type {String|Number}
     */
    topicId: null,
  
    /**
     * 帖子内容
     * @type {Object}
     */
    topic: topicInit(),
  
    /**
     * 是否有错
     */
    hasError: false,

    /**
     * 是否渲染 Markdown
     * @type {Boolean}
     */
    mdrender: true
  }
}

export const getters = {
  userInfo(state, getters, rootState) {
    return rootState.appShell.common.userInfo
  }
}

export const mutations = {
  [SET_ERROR](state, hasError) {
    state.hasError = hasError;
  },
  [SET_TOPIC](state, topic) {
    state.topic = topic
  },
  [ADD_REPLY](state, reply) {
    if (reply && reply.id) {
      state.topic.replies.unshift(reply)
      state.topic.reply_count++
    }
  },
  [ADD_UP](state, info) {
    const replies = state.topic.replies
    const replyIndex = replies.indexOf(info.reply)

    if (replyIndex !== -1) {
      if (info.status === 'up') {
        replies[replyIndex].is_uped = true
        replies[replyIndex].ups.push(info.userInfo.id)
      }
      else {
        const idIndex = replies[replyIndex].ups.indexOf(info.userInfo.id)

        replies[replyIndex].is_uped = false
        if (idIndex !== -1) {
          replies[replyIndex].ups.splice(idIndex)
        }
      }
    }
  },
  [TO_COLLECT](state, status) {
    state.topic.is_collect = !!status
  },
  [RESET_TOPIC](state) {
    setTimeout(function() {
      state.topic = topicInit()
    }, 0);
  }
}

const formatedReplies = (list) => {
  let formatReplies = []
  for (let i = 0, item; i < list.length, item = list[i]; i++) {
    if (typeof item === 'array') {
      formatReplies = [...formatReplies, ...item]
    } else {
      formatReplies.push(item)
    }
  }
  return formatReplies.reverse()
}

export const actions = {
  async getTopic({state, commit, getters}, topicId) {
    const userInfo = getters.userInfo
    state.topicId = topicId;
    const res = await get(`topic/${state.topicId}`, {
      mdrender: state.mdrender,
      accesstoken: userInfo.accessToken || ''
    });
    const data = res.data;

    if (data && data.success) {
      data.replies = formatedReplies(data.data)
      commit(SET_TOPIC, data.data)
      commit(`appShell/common/${SET_TAB}`, data.data.tab, {root: true});
    }
  },
  async replyTo({state, getters, commit}, replyObj) {
    const userInfo = getters.userInfo
    let contentHTML = null
    let reqData = {
      accesstoken: userInfo.accessToken,
      content: replyObj.content,
    }

    if (replyObj.replyId) reqData.reply_id = replyObj.replyId

    const res = await post(`/topic/${replyObj.topicId}/replies`, reqData)

    if (res && res.data.success) {
      contentHTML = document.createElement('div')
      contentHTML.classList.add('markdown-text')
      contentHTML.innerHTML = markdown.markdown.toHTML(toAuthorLink(replyObj.content))
      commit(ADD_REPLY,{
        id: res.data.reply_id,
        author: {
            loginname: userInfo.loginname,
            avatar_url: userInfo.avatar_url
        },
        content: contentHTML.outerHTML,
        ups: [],
        create_at: Date.now()
      })
      Toast('评论成功')
    }
  },
  async upTo({commit, getters}, reply) {
    if (reply && reply.id) {
      const res = await post(`/reply/${reply.id}/ups`, {
        accesstoken: getters.userInfo.accessToken,
      })
      const data = res.data

      if (data && data.success) {
        commit(ADD_UP, {
          reply, 
          status: data.action,
          userInfo: getters.userInfo
        })
      }
    }
  },
  async toCollect({ state ,commit, getters}, status) {
    const res = await post(`/topic_collect/${ status ? '' : 'de_'}collect`, {
      accesstoken: getters.userInfo.accessToken,
      topic_id: state.topic.id
    })
    const data = res.data

    if (data && data.success) {
      commit(TO_COLLECT, status)
    }
  }
}